﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Water.Web.Controls.BaseInterface;
using System.Web.UI.Design;
using System.Drawing.Design;
using System.Collections;
using System.Drawing;
using Water.Web.Controls.Design;
using Water.Resources.Globalize;
using System.Collections.Specialized;
using Water.Architecture2.IDAL;
using System.Web.UI.WebControls.Adapters;

[assembly: WebResource("Water.Resources.Default.JS.Layout.Layout.js", "text/javascript")]
namespace Water.Web.Controls
{
    [Designer(typeof(Water.Web.Controls.Design.ContainerControlDesigner))]
    [ParseChildren(true)]
    [DefaultProperty("TitleText")]
    [ToolboxData("<{0}:Container runat=server></{0}:Container>")]
    public class Container : CompositeDataBoundControl, IPostBackEventHandler/*, INamingContainer*/, ICallBackable, IUpdatedableControl, IDataItemContainer
    {
        #region private properties

        private ITemplate itemTemplate;
        private ITemplate editTemplate;
        private ITemplate insertTemplate;
        private ITemplate queryTemplate;

        private ITemplate footerTemplate;
        private ITemplate headerTemplate;

        private PreRenderPackager renderPackager;
        private string _modelValidationGroup;
        private HeaderFooterContainer _headPanel;
        private HeaderFooterContainer _footPanel;
        private ContainerItem containerItem;

        public ContainerItem ContainerItemControls
        {
            get { return containerItem; }
        }
   
        private ContainerMode _defaultMode = ContainerMode.Item;
        private OrderedDictionary _boundFieldValues;
        private DataKey _dataKey;
        private string[] _dataKeyNames;
        private OrderedDictionary _keyTable;

        private IOrderedDictionary _updateKeys;
        private IOrderedDictionary _updateNewValues;
        private IOrderedDictionary _updateOldValues;

        private IOrderedDictionary _deleteKeys;
        private IOrderedDictionary _deleteValues;

        private IOrderedDictionary _insertValues;

        private object dataItem;
        private int itemIndex;

        private static readonly object EventItemCommand = new object();
        private static readonly object EventItemCreated = new object();
        private static readonly object EventItemDeleted = new object();
        private static readonly object EventItemDeleting = new object();
        private static readonly object EventItemInserted = new object();
        private static readonly object EventItemInserting = new object();
        private static readonly object EventItemUpdated = new object();
        private static readonly object EventItemUpdating = new object();
        private static readonly object EventModeChanged = new object();
        private static readonly object EventModeChanging = new object();
        private static readonly object EventQuerying = new object();


        private bool isCallBack = false;
        private string displayDuringCallBackTextControls;

        private bool isUpdateAfterCallBack = false;
        private UpdatedableControlRenderMode renderMode = UpdatedableControlRenderMode.Span;
        private string duringCallBackText = "";
        private string updateJS = "";
        private List<string> callBackControls = new List<string>();

        private bool isSelecting = false;

        #endregion

        #region Event

        [GlobalizeDescription("OnItemCommand"), Category("Action")]
        public event ContainerCommandEventHandler ItemCommand
        {
            add
            {
                base.Events.AddHandler(EventItemCommand, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemCommand, value);
            }
        }

        [Category("Behavior"), GlobalizeDescription("OnItemCreated")]
        public event EventHandler ItemCreated
        {
            add
            {
                base.Events.AddHandler(EventItemCreated, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemCreated, value);
            }
        }

        [Category("Action"), GlobalizeDescription("OnItemDeleted")]
        public event ContainerDeletedEventHandler ItemDeleted
        {
            add
            {
                base.Events.AddHandler(EventItemDeleted, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemDeleted, value);
            }
        }

        [Category("Action"), GlobalizeDescription("OnItemDeleting")]
        public event ContainerDeleteEventHandler ItemDeleting
        {
            add
            {
                base.Events.AddHandler(EventItemDeleting, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemDeleting, value);
            }
        }

        [GlobalizeDescription("OnItemInserted"), Category("Action")]
        public event ContainerInsertedEventHandler ItemInserted
        {
            add
            {
                base.Events.AddHandler(EventItemInserted, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemInserted, value);
            }
        }

        [Category("Action"), GlobalizeDescription("DataControls_OnItemInserting")]
        public event ContainerInsertEventHandler ItemInserting
        {
            add
            {
                base.Events.AddHandler(EventItemInserting, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemInserting, value);
            }
        }

        [GlobalizeDescription("DataControls_OnItemUpdated"), Category("Action")]
        public event ContainerUpdatedEventHandler ItemUpdated
        {
            add
            {
                base.Events.AddHandler(EventItemUpdated, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemUpdated, value);
            }
        }

        [GlobalizeDescription("DataControls_OnItemUpdating"), Category("Action")]
        public event ContainerUpdateEventHandler ItemUpdating
        {
            add
            {
                base.Events.AddHandler(EventItemUpdating, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventItemUpdating, value);
            }
        }

        [GlobalizeDescription("OnModeChanged"), Category("Action")]
        public event ContaineViewModeEventHandler ModeChanged
        {
            add
            {
                base.Events.AddHandler(EventModeChanged, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventModeChanged, value);
            }
        }

        [Category("Action"), GlobalizeDescription("OnModeChanging")]
        public event ContaineViewModeEventHandler ModeChanging
        {
            add
            {
                base.Events.AddHandler(EventModeChanging, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventModeChanging, value);
            }
        }

        [Category("Action"), GlobalizeDescription("OnQuerying")]
        public event ContainerQueryEventHandler Querying
        {
            add
            {
                base.Events.AddHandler(EventQuerying, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventQuerying, value);
            }
        }


        #endregion

        public Container()
        {
            //this._headPanel = new HeaderFooterContainer();//new System.Web.UI.WebControls.Panel();
            //this._footPanel = new HeaderFooterContainer();// new System.Web.UI.WebControls.Panel();
            //this._headPanel.ID = "c_header";
            //this._footPanel.ID = "c_footer";
            if (DesignMode)
            {
                this._headPanel = new HeaderFooterContainer();
                this._footPanel = new HeaderFooterContainer();
                this.containerItem = new ContainerItem();
            }
            else
            {
                if (string.IsNullOrEmpty(this.DataSourceID) && null == this.containerItem)
                    this.containerItem = new ContainerItem();
            }
        }

        #region ICallBackable 成员

        [Browsable(true), GlobalizeCategory("AJAX"), GlobalizeDescription("IsCallBack"), DefaultValue(false)]
        public bool IsCallBack
        {
            get
            {
                return this.isCallBack;
            }
            set
            {
                this.isCallBack = value;
            }
        }
        [Browsable(true), GlobalizeCategory("AJAX"), GlobalizeDescription("CallBackTargets")]
        public string CallBackTargets
        {
            get
            {
                if (this.IsCallBack)
                {
                    return this.displayDuringCallBackTextControls;
                }
                return string.Empty;
            }
            set
            {
                this.displayDuringCallBackTextControls = value;
            }
        }

        #endregion

        #region IUpdatedableControl 成员
        [Browsable(true), GlobalizeCategory("AJAX"), GlobalizeDescription("AutoUpdatedAfterCallBack"), DefaultValue(false)]
        public bool AutoUpdatedAfterCallBack
        {
            get
            {
                return this.isUpdateAfterCallBack;
            }
            set
            {
                this.isUpdateAfterCallBack = value;
            }
        }
        [Browsable(false), DefaultValue(false)]
        public bool IsUpdatedAfterCallBack
        {
            get
            {
                return this.isUpdateAfterCallBack;
            }
            set
            {
                this.isUpdateAfterCallBack = value;
            }
        }

        [Browsable(true), GlobalizeCategory("AJAX"), GlobalizeDescription("DuringCallBackText")]
        public string DuringCallBackText
        {
            get
            {
                if (this.duringCallBackText != null)
                {
                    return this.duringCallBackText;
                }
                return string.Empty;
            }
            set
            {
                this.duringCallBackText = value;
            }
        }
        [Browsable(true), GlobalizeCategory("AJAX"), GlobalizeDescription("RenderMode"), DefaultValue(UpdatedableControlRenderMode.Span)]
        public UpdatedableControlRenderMode RenderMode
        {
            get
            {
                return this.renderMode;
            }
            set
            {
                this.renderMode = value;
            }
        }

        [Browsable(false), GlobalizeCategory("AJAX"), GlobalizeDescription("UpdateJS")]
        public virtual string UpdateJS
        {
            get
            {
                return this.updateJS;
            }
            set
            {
                this.updateJS = value;
            }
        }

        [Browsable(false)]
        public List<string> CallBackControls
        {
            get { return callBackControls; }
            set { callBackControls = value; }
        }
        #endregion


        #region On...
        protected virtual void OnModeChanged(EventArgs e)
        {
            EventHandler handler = (EventHandler)base.Events[EventModeChanged];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnModeChanging(ContainerViewModeEventArgs e)
        {
            //bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContaineViewModeEventHandler handler = (ContaineViewModeEventHandler)base.Events[EventModeChanging];
            if (handler != null)
            {
                handler(this, e);
            }
            else if (/*!isBoundUsingDataSourceID &&*/ e.Cancel)
            {
                throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContianerUnhandledEvent"), this.ID, "ModeChanging"));
            }
        }

        protected virtual void OnItemCommand(ContainerCommandEventArgs e)
        {
            ContainerCommandEventHandler handler = (ContainerCommandEventHandler)base.Events[EventItemCommand];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnItemCreated(EventArgs e)
        {
            EventHandler handler = (EventHandler)base.Events[EventItemCreated];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnItemUpdating(ContainerUpdateEventArgs e)
        {
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContainerUpdateEventHandler handler = (ContainerUpdateEventHandler)base.Events[EventItemUpdating];
            if (handler != null)
            {
                handler(this, e);
            }
            else if (!isBoundUsingDataSourceID && !e.Cancel)
            {
                throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContianerUnhandledEvent"), this.ID, "ItemUpdating"));
            }
        }

        protected virtual void OnItemUpdated(ContainerUpdatedEventArgs e)
        {
            ContainerUpdatedEventHandler handler = (ContainerUpdatedEventHandler)base.Events[EventItemUpdated];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnItemInserted(ContainerInsertedEventArgs e)
        {
            ContainerInsertedEventHandler handler = (ContainerInsertedEventHandler)base.Events[EventItemInserted];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnItemInserting(ContainerInsertEventArgs e)
        {
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContainerInsertEventHandler handler = (ContainerInsertEventHandler)base.Events[EventItemInserting];
            if (handler != null)
            {
                handler(this, e);
            }
            else if (!isBoundUsingDataSourceID && !e.Cancel)
            {
                throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContianerUnhandledEvent"), this.ID, "ItemInserting"));
            }
        }

        protected virtual void OnItemDeleted(ContainerDeletedEventArgs e)
        {
            ContainerDeletedEventHandler handler = (ContainerDeletedEventHandler)base.Events[EventItemDeleted];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnItemDeleting(ContainerDeleteEventArgs e)
        {
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContainerDeleteEventHandler handler = (ContainerDeleteEventHandler)base.Events[EventItemDeleting];
            if (handler != null)
            {
                handler(this, e);
            }
            else if (!isBoundUsingDataSourceID && !e.Cancel)
            {
                throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContianerUnhandledEvent"), this.ID, "ItemDeleting"));
            }
        }

        protected virtual void OnQuerying(ContainQueryEventArgs e)
        {
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContainerQueryEventHandler handler = (ContainerQueryEventHandler)base.Events[EventQuerying];
            if (handler != null)
            {
                handler(this, e);
            }
            else if (!isBoundUsingDataSourceID && !e.Cancel)
            {
                throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContianerUnhandledEvent"), this.ID, "Querying"));
            }
        }


        #endregion


        #region  properties

        #region template


        [Browsable(false)]
        [TemplateContainer(typeof(ContainerItem), BindingDirection.TwoWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ItemTemplate
        {
            get { return itemTemplate; }
            set { itemTemplate = value; base.ChildControlsCreated = false; }
        }

        [Browsable(false)]
        [TemplateContainer(typeof(ContainerItem), BindingDirection.TwoWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate InsertTemplate
        {
            get { return insertTemplate; }
            set { insertTemplate = value; base.ChildControlsCreated = false;}
        }

        [Browsable(false)]
        [TemplateContainer(typeof(ContainerItem), BindingDirection.TwoWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate EditTemplate
        {
            get { return editTemplate; }
            set { editTemplate = value; base.ChildControlsCreated = false; }
        }

        [Browsable(false)]
        [TemplateContainer(typeof(ContainerItem), BindingDirection.TwoWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate QueryTemplate
        {
            get { return queryTemplate; }
            set { queryTemplate = value; base.ChildControlsCreated = false; }
        }


        [Browsable(false)]
        [TemplateContainer(typeof(HeaderFooterContainer),BindingDirection.OneWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate FooterTemplate
        {
            get { return footerTemplate; }
            set { footerTemplate = value; base.ChildControlsCreated = false; }
        }


        [Browsable(false)]
        [TemplateContainer(typeof(HeaderFooterContainer),BindingDirection.OneWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate HeaderTemplate
        {
            get { return headerTemplate; }
            set { headerTemplate = value; base.ChildControlsCreated = false; }
        }
        #endregion

        #region properties not template

        public PreRenderPackager RenderPackager
        {
            get { return renderPackager; }
            set { renderPackager = value; }
        }

        private bool zoomable = true;

        [Browsable(true), DefaultValue(true), GlobalizeDescription("Zoomabel"), Category("Behavior")]
        public virtual bool Zoomable
        {
            get { return zoomable; }
            set { zoomable = value; }
        }


        private string titleText;

        [Browsable(true), GlobalizeDescription("TitleText"), Category("Appearance"), Bindable(true)]
        public virtual string TitleText
        {
            get {
                if(string.IsNullOrEmpty(titleText) && !string.IsNullOrEmpty(TitleTextPrompt))
                    return Water.Web.Prompt.PromptProxy.GetPromptDesc(TitleTextPrompt);
                return titleText; }
            set { titleText = value; }
        }

        private string titleTextPrompt;

        [Browsable(true), GlobalizeDescription("TitleTextPrompt"), GlobalizeCategory("PROMPT"), Bindable(true)]
        public virtual string TitleTextPrompt
        {
            get { return titleTextPrompt; }
            set { titleTextPrompt = value; }
        }


        private string titleImageUrl = Path.ResourcePath + "Images/Layout/info.gif";//"~/Resources/Default/Images/Layout/info.gif";

        [Browsable(true), GlobalizeDescription("TitleImageUrl"), Category("Appearance"), Bindable(true)/*, DefaultValue("~/Resources/Default/Images/Layout/info.gif")*/, Editor("System.Web.UI.Design.ImageUrlEditor", typeof(UITypeEditor))]
        public virtual string TitleImageUrl
        {
            get { return titleImageUrl; }
            set { titleImageUrl = value; }
        }
        private TextAlign zoomImageAlign = TextAlign.Right;

        [Browsable(true), GlobalizeDescription("ZoomImageAlign"), Category("Appearance")]
        public virtual TextAlign ZoomImageAlign
        {
            get { return zoomImageAlign; }
            set { zoomImageAlign = value; }
        }
        private int columns = 1;

        [Browsable(true), GlobalizeDescription("Columns"), Category("Appearance"), Bindable(true), DefaultValue(1)]
        public virtual int Columns
        {
            get { return columns; }
            set { columns = value; }
        }
        private bool isDisplayBorder = true;

        [Browsable(true), GlobalizeDescription("IsDisplayBorder"), Category("Appearance"), Bindable(true), DefaultValue(true)]
        public virtual bool DisplayBorder
        {
            get { return isDisplayBorder; }
            set { isDisplayBorder = value; }
        }

        private bool promptable = true;

        [Browsable(true), GlobalizeDescription("Promptabel"), Category("Behavior"), Bindable(true), DefaultValue(true)]
        public bool Promptable
        {
            get { return promptable; }
            set { promptable = value; }
        }

        private HeaderFooterInfo header = new HeaderFooterInfo();

        [Browsable(true), NotifyParentProperty(true), GlobalizeDescription("Header"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual HeaderFooterInfo Header
        {
            get { return header; }
            set { header = value; }
        }

        private HeaderFooterInfo footer = new HeaderFooterInfo();

        [Browsable(true), NotifyParentProperty(true), GlobalizeDescription("Footer"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public HeaderFooterInfo Footer
        {
            get { return footer; }
            set { footer = value; }
        }

        private string containStyle;

        [Browsable(true), GlobalizeDescription("ContainStyle"), Category("Appearance")]
        public string ContainStyle
        {
            get { return containStyle; }
            set { containStyle = value; }
        }

        private string cssStyleTitle = "layout";

        protected string CssStyleTitle
        {
            get { return cssStyleTitle; }
            set { cssStyleTitle = value; }
        }


        private string src;


        [Browsable(true), DefaultValue(""), UrlProperty("*.aspx"), GlobalizeDescription("Src"), Editor("System.Web.UI.Design.UrlEditor", typeof(UITypeEditor)), Themeable(false), Category("Behavior")] 
        public string Src
        {
            get { return src; }
            set { src = value; }
        }

        private bool onlyLayout = false;

        [Browsable(true), GlobalizeDescription("OnlyLayout"), Category("Behavior")]
        public bool OnlyLayout
        {
            get { return onlyLayout; }
            set { onlyLayout = value; }
        }


        private LayoutType packageType = LayoutType.Table;

        [Browsable(true), GlobalizeDescription("PackageType"), Category("Appearance"), DefaultValue(LayoutType.Table)]
        public LayoutType PackageType
        {
            get { return packageType; }
            set { packageType = value; }
        }

        [Browsable(true), GlobalizeDescription("Mode"), Category("Appearance"), DefaultValue(ContainerMode.Item)]
        public ContainerMode ViewMode
        {
            get
            {
                object mode = ViewState["ViewMode"];
                return (mode == null) ? ContainerMode.Item : (ContainerMode)mode;
            }
            set
            {
                ViewState["ViewMode"] = value;
            }
        }

        [Browsable(true), Category("Behavior"), DefaultValue(false), GlobalizeDescription("EnableModelValidation")]
        public virtual bool EnableModelValidation
        {
            get
            {
                object obj2 = this.ViewState["EnableModelValidation"];
                return ((obj2 != null) && ((bool)obj2));
            }
            set
            {
                this.ViewState["EnableModelValidation"] = value;
            }
        }

        [Browsable(true), DefaultValue(ContainerMode.Item), Category("Behavior"), GlobalizeDescription("DefaultMode")]
        public virtual ContainerMode DefaultMode
        {
            get
            {
                return this._defaultMode;
            }
            set
            {
                this._defaultMode = value;
            }
        }

        private OrderedDictionary KeyTable
        {
            get
            {
                if (this._keyTable == null)
                {
                    this._keyTable = new OrderedDictionary(this.DataKeyNamesInternal.Length);
                }
                return this._keyTable;
            }
        }

        [GlobalizeDescription("DataKey"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
        public virtual DataKey DataKey
        {
            get
            {
                if (this._dataKey == null)
                {
                    this._dataKey = new DataKey(this.KeyTable);
                }
                return this._dataKey;
            }
        }

        private IOrderedDictionary BoundFieldValues
        {
            get
            {
                if (this._boundFieldValues == null)
                {
                    int capacity = 0x19;
                    this._boundFieldValues = new OrderedDictionary(capacity);
                }
                return this._boundFieldValues;
            }
        }

        private string[] DataKeyNamesInternal
        {
            get
            {
                object obj2 = this._dataKeyNames;
                if (obj2 != null)
                {
                    return (string[])obj2;
                }
                return new string[0];
            }
        }

        [GlobalizeDescription("DataKeyNames"), DefaultValue((string)null), Editor("System.Web.UI.Design.WebControls.DataFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), TypeConverter(typeof(StringArrayConverter)), Category("Data")]
        public virtual string[] DataKeyNames
        {
            get
            {
                object obj2 = this._dataKeyNames;
                if (obj2 != null)
                {
                    return (string[])((string[])obj2).Clone();
                }
                return new string[0];
            }
            set
            {
                if (!Water.Util.Util.CompareStringArrays(value, this.DataKeyNamesInternal))
                {
                    if (value != null)
                    {
                        this._dataKeyNames = (string[])value.Clone();
                    }
                    else
                    {
                        this._dataKeyNames = null;
                    }
                    //this._keyTable = null;
                    if (base.Initialized)
                    {
                        base.RequiresDataBinding = true;
                    }
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ContainerMode CurrentMode
        {
            get
            {
                return this.ViewMode;
            }
        }

        [Browsable(true), GlobalizeDescription("DisplayContain"), Category("Appearance"), DefaultValue(true)]
        public bool DisplayContain
        {
            get 
            {
                object obj = this.ViewState["ContainDisplay"];
                if (obj != null)
                    return (bool)obj;
                return true;
            }
            set 
            {
                this.ViewState["ContainDisplay"]=value;
            }
        }

        [Browsable(false), DefaultValue(false)]
        public bool IsSelecting
        {
            get { return isSelecting; }
        }
        #endregion

        #region insert update delete where
        private Hashtable insertFields = new Hashtable();

        [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
        public Hashtable InsertFields
        {
            get { return insertFields; }
        }

        private WhereFields whereFields = new WhereFields();

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public WhereFields WhereFields
        {
            get
            {
                if (null != this.containerItem)
                {
                    if (this.containerItem.WhereFields.Count > 0)
                        this.whereFields = this.containerItem.WhereFields;
                }
                return whereFields;
            }
        }

        private Hashtable updateFields = new Hashtable();

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public Hashtable UpdateFields
        {
            get { return updateFields; }
        }

        private Hashtable updateWhereFields = new Hashtable();

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public Hashtable UpdateWhereFields
        {
            get { return updateWhereFields; }
        }

        private Hashtable deleteFields = new Hashtable();

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public Hashtable DeleteFields
        {
            get { return deleteFields; }
        }
        #endregion

        #endregion

        #region override

        protected override void OnInit(EventArgs e)
        {
            if (this.Page != null)
                this.Page.RegisterRequiresControlState(this);
            base.OnInit(e);
            if (!DesignMode)
                PageManager.Register(this);
        }

        protected override void OnPreRender(EventArgs e)
        {
            this.Page.ClientScript.RegisterClientScriptResource(typeof(Container), "Water.Resources.Default.JS.Layout.Layout.js");
            PageManager.RegisterPageStyleSheet(this, "Layout_CSS", "CSS/Layout.css");
            base.OnPreRender(e);
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
            if (this.packageType == LayoutType.Table)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
                //writer.AddAttribute(HtmlTextWriterAttribute.Style, "table-layout: fixed;");
            }
            else if (this.packageType == LayoutType.Div)
                writer.AddAttribute(HtmlTextWriterAttribute.Class, "container_p");
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                HtmlTextWriterTag tag;
                switch (this.packageType)
                {
                    case LayoutType.Table:
                        tag = HtmlTextWriterTag.Table;
                        break;
                    case LayoutType.Div:
                        tag = HtmlTextWriterTag.Div;
                        break;
                    default:
                        tag = HtmlTextWriterTag.Table;
                        break;
                }
                return tag;
            }
        }

        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            if (this is IUpdatedableControl)
                Marker.WriteAJAXBegin(writer, this, false, renderPackager);
            base.RenderBeginTag(writer);

            if (this.packageType == LayoutType.Table)
            {
                writer.RenderBeginTag(HtmlTextWriterTag.Tr);//tr
                writer.AddAttribute(HtmlTextWriterAttribute.Valign, "top");
                writer.RenderBeginTag(HtmlTextWriterTag.Td);//td
            }

            if (!this.OnlyLayout)
            {
                if (DisplayBorder)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_1 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();

                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_2 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();

                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_3 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();
                }

                if (DisplayBorder)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_middle");//*****
                }
                writer.RenderBeginTag(HtmlTextWriterTag.Div);  //not end

                if (DisplayBorder)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_header");
                }
                else
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_header_noborder");
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                RenderTitleBar(writer);// render title bar
                writer.RenderEndTag();

                if (this.Height != Unit.Empty)
                    this.ContainStyle += @";height:"+this.Height.ToString()+";";
                    
                if (!this.DisplayContain)
                    this.ContainStyle += @";display:none;";
                writer.AddAttribute(HtmlTextWriterAttribute.Style, this.ContainStyle);
                writer.AddAttribute(HtmlTextWriterAttribute.Id, "_" + this.ClientID + "_contain_");
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_contain");//layout contain begin
                
                writer.RenderBeginTag(HtmlTextWriterTag.Div); //not end
            }

        }

        public override void RenderEndTag(HtmlTextWriter writer)
        {
            if (!this.OnlyLayout)
            {
                writer.RenderEndTag();//layout contain end


                //writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_bottom");
                //writer.RenderBeginTag(HtmlTextWriterTag.Div);// bottom

                if (this.footerTemplate != null)
                {
                    string _fb = "";
                    if (!this.isDisplayBorder)
                        _fb = "_n";

                    if (!string.IsNullOrEmpty(this.Footer.CssClass))
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_footer"+_fb+" " + this.Footer.CssClass);
                    else
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_footer"+_fb);//footer 

                    if (!string.IsNullOrEmpty(this.Footer.Align.ToString()))
                        writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, this.Footer.Align.ToString());
                    if(!DisplayContain)
                        writer.AddAttribute(HtmlTextWriterAttribute.Style, @"display:none;");

                    writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_footer");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    RenderFooterBar(writer);
                    writer.RenderEndTag();
                }

                //writer.RenderEndTag();//bottom end
                writer.RenderEndTag();//layout middle end

                if (DisplayBorder)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_4 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();

                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_5 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();

                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_1 ");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    writer.RenderEndTag();

                }



            }
            if (this.packageType == LayoutType.Table)
            {
                writer.RenderEndTag();//td end
                writer.RenderEndTag();//tr end
            }


            base.RenderEndTag(writer);
            if (this is IUpdatedableControl)
                Marker.WriteAJAXEnd(writer, this);

        }

        protected override void CreateChildControls()
        {
            if (containerItem != null)
                this.containerItem.Controls.Clear();
            this.Controls.Clear();

            if (DesignMode)
            {
                this.containerItem = new ContainerItem();
                InstantiateTemplate(containerItem, ViewMode, false);
            }
            else
            {
                base.CreateChildControls();
            }
            if (string.IsNullOrEmpty(this.DataSourceID))
                InstantiateTemplateWithoutDataSourceID(this.ViewMode);

            CreateHeaderAndFooter();
            base.ChildControlsCreated = true;
            base.ClearChildViewState();
        }

        protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
        {
            if (!DesignMode)
            {
                bool _flag = false;
                object _dataItem = null;
                if (dataSource != null)
                {
                    IEnumerator enumerator = dataSource.GetEnumerator();
                    _flag = enumerator.MoveNext();
                    if (_flag)
                    {
                        _dataItem = enumerator.Current;

                        if (dataBinding && DataKeyNamesInternal.Length != 0)
                        {
                            foreach (string str in DataKeyNamesInternal)
                            {
                                object propertyValue = DataBinder.GetPropertyValue(_dataItem, str);
                                if (this.KeyTable.Contains(str))
                                    this.KeyTable.Remove(str);
                                this.KeyTable.Add(str, propertyValue);
                            }
                            this._dataKey = new DataKey(this.KeyTable);
                        }
                    }
                }
                this.dataItem = _dataItem;
                if (string.IsNullOrEmpty(this.DataSourceID))
                    containerItem = new ContainerItem();
                else
                    containerItem = new ContainerItem(_dataItem);
                InstantiateTemplate(containerItem, this.ViewMode, dataBinding);
                if (dataBinding)
                    this.DataBind(false);
                CreateHeaderAndFooterPanel();
                return 1;
            }
            else
                return 1;
        }

        protected override void EnsureDataBound()
        {
            if (base.RequiresDataBinding && (this.ViewMode == ContainerMode.Insert))
            {
                this.OnDataBinding(EventArgs.Empty);
                base.RequiresDataBinding = false;
                base.MarkAsDataBound();
                this.PerformDataBinding(null);
                this.OnDataBound(EventArgs.Empty);
            }
            else
            {
                base.EnsureDataBound();
            }
        }

        private void CreateHeaderAndFooter()
        {
            if (this.headerTemplate != null)
            {
                if (this._headPanel == null)
                {
                    this._headPanel = new HeaderFooterContainer();
                    this._headPanel.DataItem = this.dataItem;
                }
                this.headerTemplate.InstantiateIn(this._headPanel);
                this.Controls.Add(this._headPanel);
                _headPanel.DataBind();
            }
            if (this.footerTemplate != null)
            {
                if (this._footPanel == null)
                {
                    this._footPanel = new HeaderFooterContainer();
                    this._footPanel.DataItem = this.dataItem;
                }
                this.footerTemplate.InstantiateIn(this._footPanel);
                this.Controls.Add(this._footPanel);
                _footPanel.DataBind();
            }
        }

        private void CreateHeaderAndFooterPanel()
        { 
                if (this._headPanel == null)
                {
                    this._headPanel = new HeaderFooterContainer();
                    this._headPanel.DataItem = this.dataItem;
                }
                if (this._footPanel == null)
                {
                    this._footPanel = new HeaderFooterContainer();
                    this._footPanel.DataItem = this.dataItem;
                }
                
        }

        protected virtual void InstantiateTemplateWithoutDataSourceID(ContainerMode mode)
        {
            if (containerItem != null)
                this.containerItem.Controls.Clear();
            ITemplate _template;
            switch (mode)
            {
                case ContainerMode.Item:
                    _template = this.ItemTemplate;
                    break;
                case ContainerMode.Edit:
                    _template = this.EditTemplate;
                    break;
                case ContainerMode.Insert:
                    _template = this.InsertTemplate;
                    break;
                case ContainerMode.Query:
                    _template = this.QueryTemplate;
                    break;
                default:
                    _template = this.ItemTemplate;
                    break;
            }
            if (_template != null)
            {
                if (null == this.containerItem)
                    this.containerItem = new ContainerItem();
                _template.InstantiateIn(this.containerItem);
            }

            this.Controls.Add(containerItem);

            this.OnItemCreated(EventArgs.Empty);
        }

        protected virtual void InstantiateTemplate(ContainerItem containerItem, ContainerMode mode, bool dataBinding)
        {
            ITemplate _template;
            switch (mode)
            {
                case ContainerMode.Item:
                    _template = this.ItemTemplate;
                    break;
                case ContainerMode.Edit:
                    _template = this.EditTemplate;
                    break;
                case ContainerMode.Insert:
                    _template = this.InsertTemplate;
                    break;
                case ContainerMode.Query:
                    _template = this.QueryTemplate;
                    break;
                default:
                    _template = this.ItemTemplate;
                    break;
            }
            if (_template != null && containerItem != null)
                _template.InstantiateIn(containerItem);

            this.Controls.Add(containerItem);

            this.OnItemCreated(EventArgs.Empty);
        }

        protected override void RenderChildren(HtmlTextWriter writer)
        {
            EnsureChildControls();
            if (!string.IsNullOrEmpty(this.Src))
            {
                RenderIframe(writer);
            }
            else
            {
                if (this.Promptable && this.Columns > 0)
                    RenderLayoutContent(this.containerItem, writer);
                else
                    containerItem.RenderControl(writer);
            }
        }

        protected override bool OnBubbleEvent(object source, EventArgs e)
        {
            bool causesValidation = false;
            string validationGroup = string.Empty;
            ContainerCommandEventArgs args = new ContainerCommandEventArgs(source, (CommandEventArgs)e);
            if (args != null)
            {
                IButtonControl commandSource = args.CommandSource as IButtonControl;
                if (commandSource != null)
                {
                    causesValidation = commandSource.CausesValidation;
                    validationGroup = commandSource.ValidationGroup;
                }
            }
            bool _return= this.HandleEvent(source, args, causesValidation, validationGroup);
            return _return;
        }

        protected override void PerformDataBinding(IEnumerable data)
        {
            base.PerformDataBinding(data);
            if ((base.IsBoundUsingDataSourceID && (this.ViewMode == ContainerMode.Edit)) && base.IsViewStateEnabled)
            {
                this.ExtractRowValues(this.BoundFieldValues, false);
            }
        }

        #endregion

        #region method help


        private void RenderTitleBar(HtmlTextWriter writer)
        {
            //添加标题栏 table
            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
            writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
            writer.AddAttribute(HtmlTextWriterAttribute.Style, "width: 100%;height: 100%");
            writer.RenderBeginTag(HtmlTextWriterTag.Table);//table begin
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            //writer.RenderBeginTag(HtmlTextWriterTag.Td);  //第一列开始

            //是否显示TitleImage
            if (!string.IsNullOrEmpty(this.TitleImageUrl))
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_titleimage");
                writer.RenderBeginTag(HtmlTextWriterTag.Td);   //title image td

                writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Src, this.ResolveClientUrl(this.TitleImageUrl));

                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
                writer.RenderEndTag();//title image td end 
            }
            writer.RenderBeginTag(HtmlTextWriterTag.Td);  //第一列开始

            //是否显示TitleText
            if (!string.IsNullOrEmpty(TitleText))
            {
                writer.Write("&nbsp;");
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_title");
                writer.RenderBeginTag(HtmlTextWriterTag.Span);//span begin
                writer.Write(TitleText);
                writer.RenderEndTag();//span end
            }
            if (this.ZoomImageAlign == TextAlign.Left)
                RenderzoomImg(writer);

            writer.RenderEndTag();  // td第一列结束
            //writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");

            if (!string.IsNullOrEmpty(this.Header.CssClass))
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.Header.CssClass);

            if (!string.IsNullOrEmpty(this.Header.Align.ToString()) && this.Header.Align != HorizontalAlign.NotSet)
                writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, this.Header.Align.ToString());
            else
                writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_header_ctl");
            writer.RenderBeginTag(HtmlTextWriterTag.Td);   //td 第二列开始

            if (this.headerTemplate != null)
            {
                if (!this.Controls.Contains(this._headPanel))
                   this.Controls.Add(this._headPanel);
                _headPanel.RenderControl(writer);
            }


            writer.RenderEndTag(); //td 第二列结束

            //呈现缩放图片
            if (this.ZoomImageAlign == TextAlign.Right)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "18px");
                writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
                writer.RenderBeginTag(HtmlTextWriterTag.Td);   //td 第三列开始


                RenderzoomImg(writer);

                writer.RenderEndTag(); //td 第三列结束
            }

            writer.RenderEndTag();
            writer.RenderEndTag();//table end
        }

        private void RenderFooterBar(HtmlTextWriter writer)
        {
            if (this.footerTemplate != null)
            {
                if(!this.Controls.Contains(this._footPanel))
                   this.Controls.Add(this._footPanel);
                _footPanel.RenderControl(writer);
            }
        }

        protected virtual void RenderzoomImg(HtmlTextWriter writer)
        {
            /*
            if (this.Zoomable)
            {
                writer.Write("&nbsp;");
                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "$j.isContainDisplay('" + this.ClientID + "',this)");
                writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                if(this.DisplayContain)
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.ResolveClientUrl(Path.ResourcePath) + "Images/Layout/minus.gif");
                else
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.ResolveClientUrl(Path.ResourcePath) + "Images/Layout/plus.gif");

                writer.AddAttribute(HtmlTextWriterAttribute.Class,"layout_zoom");

                writer.RenderBeginTag(HtmlTextWriterTag.Img);//img begin
                writer.RenderEndTag();//img end
                writer.Write("&nbsp;");
            }
            */
            if (this.Zoomable)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "$j.isContainDisplay('" + this.ClientID + "',this)");
                if (this.DisplayContain)
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "layout_zoom layout-tool layout-tool-minus");
                else
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "layout_zoom layout-tool layout-tool-plus");
                writer.RenderBeginTag(HtmlTextWriterTag.Div);//div begin
                writer.RenderEndTag();//img end
            }
        }

        private string RenderPrompt(Control c)
        {
            string prompt = "";
            string promptDesc = "";

            if (c is IPrompt)
                prompt = ((IPrompt)c).Prompt;
            else if (c is WebControl)
                prompt = ((WebControl)c).Attributes["Prompt"];
            else if (c is System.Web.UI.HtmlControls.HtmlControl)
                prompt = ((System.Web.UI.HtmlControls.HtmlControl)c).Attributes["Prompt"];

            try
            {
                if (DesignMode)
                    promptDesc = prompt.ToUpper();
                else
                    promptDesc = Water.Web.Prompt.PromptProxy.GetPromptDesc(prompt);
            }
            catch
            {
                promptDesc = "";
            }

            return promptDesc;


            //if (c is IPrompt)
            //{
            //    string prompt= ((IPrompt)c).Prompt;
            //}
            //else if (c is WebControl)
            //{
            //    try
            //    {
            //        string prompt = ((WebControl)c).Attributes["Prompt"];
            //        return Water.Web.Prompt.PromptProxy.GetPromptDesc(prompt);

            //    }
            //    catch
            //    {
            //        return "";
            //    }
            //}
            //else if (c is System.Web.UI.HtmlControls.HtmlControl)
            //{
            //    try
            //    {
            //        string prompt = ((System.Web.UI.HtmlControls.HtmlControl)c).Attributes["Prompt"];
            //        return Water.Web.Prompt.PromptProxy.GetPromptDesc(prompt); ;
            //    }
            //    catch
            //    {
            //        return "";
            //    }
            //}
            //else
            //{
            //    return "";
            //}
        }

        private string RenderColSpan(Control c)
        {
            if (c is IPrompt)
            {
                return ((IPrompt)c).ColSpan.ToString();
            }
            else if (c is WebControl)
            {
                try
                {
                    return ((WebControl)c).Attributes["ColSpan"].ToString();
                }
                catch
                {
                    return "0";
                }
            }
            else if (c is System.Web.UI.HtmlControls.HtmlControl)
            {
                try
                {
                    return ((System.Web.UI.HtmlControls.HtmlControl)c).Attributes["ColSpan"].ToString();
                }
                catch
                {
                    return "0";
                }
            }
            else
            {
                return "0";
            }
        }

        private void RenderLayoutContent(Control control, HtmlTextWriter writer)
        {
            int controlCount = 0;
            if (control != null)
            {
                List<Control> cl = new List<Control>();
                foreach (Control c in control.Controls)
                {
                    if (!(c is System.Web.UI.LiteralControl && ((System.Web.UI.LiteralControl)c).Text.Trim().Length == 0))
                        cl.Add(c);
                }
                controlCount = cl.Count;//control.Controls.Count;
                writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "1");
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_prompt_table");
                writer.RenderBeginTag(HtmlTextWriterTag.Table);//table begin
                int trCount = 0;//tr 数
                int tdCount = 0;//td 数，每行开始重新付为0
                // ArrayList arrayList = new ArrayList();
                //foreach (Control c in control.Controls)
                foreach (Control c in cl)
                {
                    --controlCount;

                    //if (controlCount != 0)
                    //{
                        //--controlCount;
                        //输出tr开始标记
                        if (tdCount == 0)
                        {
                            if (trCount % 2 != 0)//交替行
                            {
                                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_prompt_table_alternating_tr");
                            }
                            else
                            {
                                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_prompt_table_normal_tr");
                            }
                            writer.RenderBeginTag(HtmlTextWriterTag.Tr);//tr begin

                            //tr begin
                        }

                        //td begin----prompt 输出td Prompt
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_prompt_table_prompt_td");
                        writer.RenderBeginTag(HtmlTextWriterTag.Td);

                        writer.Write(RenderPrompt(c));

                        writer.RenderEndTag();
                        //td end-----prompt

                        //td begin----control//输出td control
                        int colSpan = 0;
                        colSpan = Convert.ToInt32(RenderColSpan(c));//得到ColSpan
                        int i = 0;
                        if (colSpan > 1)
                        {
                            if (colSpan * 2 > (this.columns * 2 - tdCount))
                            {
                                writer.AddAttribute(HtmlTextWriterAttribute.Colspan, Convert.ToString(this.columns * 2 - tdCount - 1));
                                i = this.columns * 2 - tdCount;
                            }
                            else
                            {
                                writer.AddAttribute(HtmlTextWriterAttribute.Colspan, Convert.ToString(colSpan * 2 - 1));
                                i = colSpan * 2;
                            }
                        }
                        else
                        {
                            i = 2;
                        }
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_prompt_table_control_td");
                        if (this.DesignMode)
                            writer.AddAttribute(HtmlTextWriterAttribute.Style, "background-color:#f2f2f2");

                        writer.RenderBeginTag(HtmlTextWriterTag.Td);
                        //CreateWhereFields(c);
                        c.RenderControl(writer);
                        writer.RenderEndTag();
                        tdCount = tdCount + i;

                   //}// if end
                        if (controlCount == 0 && tdCount < this.columns * 2)
                        {
                            int n = this.columns * 2 - tdCount;
                            for (int j = 1; j <= n; j++)
                            {
                                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                                writer.RenderEndTag();
                                ++tdCount;
                            }
                        }

                        //输出tr结束标记
                        if (tdCount == this.columns * 2)
                        {
                            writer.RenderEndTag();//tr end
                            tdCount = 0;
                            ++trCount;
                        }
                    //}// if end
                }  //foreach结束


                writer.RenderEndTag();//table end
            }
        }

        private void RenderIframe(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_iframe");

            RenderSrc(writer);

            writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssStyleTitle + "_iframe");
            writer.AddAttribute("frameborder", "0");
            writer.AddAttribute("scrolling", "Auto");
            writer.AddAttribute("marginwidth", "0");
            writer.AddAttribute("marginheight", "0");
            writer.RenderBeginTag(HtmlTextWriterTag.Iframe);
            writer.RenderEndTag();
        }

        protected virtual void RenderSrc(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Src); 
        }

        protected virtual void ExtractRowValues(IOrderedDictionary fieldValues, bool includeKeys)
        {
            if (fieldValues != null)
            {
                IBindableTemplate itemTemplate = null;
                if ((this.ViewMode == ContainerMode.Item) && (this.ItemTemplate != null))
                {
                    itemTemplate = this.ItemTemplate as IBindableTemplate;
                }
                else if ((this.ViewMode == ContainerMode.Edit) && (this.EditTemplate != null))
                {
                    itemTemplate = this.EditTemplate as IBindableTemplate;
                }
                else if ((this.ViewMode == ContainerMode.Insert) && (this.InsertTemplate != null))
                {
                    itemTemplate = this.InsertTemplate as IBindableTemplate;
                }
                else if ((this.ViewMode == ContainerMode.Query) && (this.QueryTemplate != null))
                {
                    itemTemplate = this.QueryTemplate as IBindableTemplate;
                }
                string[] dataKeyNamesInternal = this.DataKeyNamesInternal;
 
                if (itemTemplate != null)
                {
                    if ((this.containerItem != null) && (itemTemplate != null))
                    {
                        foreach (DictionaryEntry entry in itemTemplate.ExtractValues(this.containerItem))
                        {
                            if (includeKeys || (Array.IndexOf(dataKeyNamesInternal, entry.Key) == -1))
                            {
                                fieldValues[entry.Key] = entry.Value;
                            }

                            if (DataKeyNamesInternal.Length != 0 && null == this._dataKey && Array.IndexOf(dataKeyNamesInternal, entry.Key) != -1)
                            {
                                this.KeyTable.Add(entry.Key,entry.Value);
                            }
                        }

                        if (DataKeyNamesInternal.Length != 0 && null == this._dataKey)
                          this._dataKey = new DataKey(this.KeyTable);
                    }
                }
            }
        }

        protected virtual void ExtractValues()
        {
            IBindableTemplate itemTemplate = null;
            if ((this.ViewMode == ContainerMode.Item) && (this.ItemTemplate != null))
            {
                itemTemplate = this.ItemTemplate as IBindableTemplate;
            }
            else if ((this.ViewMode == ContainerMode.Edit) && (this.EditTemplate != null))
            {
                itemTemplate = this.EditTemplate as IBindableTemplate;
            }
            else if ((this.ViewMode == ContainerMode.Insert) && (this.InsertTemplate != null))
            {
                itemTemplate = this.InsertTemplate as IBindableTemplate;
            }
            else if ((this.ViewMode == ContainerMode.Query) && (this.QueryTemplate != null))
            {
                itemTemplate = this.QueryTemplate as IBindableTemplate;
            }
            string[] dataKeyNamesInternal = this.DataKeyNamesInternal;
            if (itemTemplate != null)
            {
                if ((this.containerItem != null) && (itemTemplate != null))
                {
                    if (this.ViewMode == ContainerMode.Query)
                    {
                        foreach (DictionaryEntry entry in itemTemplate.ExtractValues(this.containerItem))
                        {
                            //if (includeKeys || (Array.IndexOf(dataKeyNamesInternal, entry.Key) == -1))
                            //{
                            //    fieldValues[entry.Key] = entry.Value;
                            //}
                            if (!string.IsNullOrEmpty(entry.Value.ToString()) && null != entry.Value)
                                this.whereFields.Add(entry.Key.ToString(), OperatorType.Equals, entry.Value);

                        }
                    }
                }
            }
        }

        private bool PageIsValidAfterModelException()
        {
            if (this._modelValidationGroup == null)
            {
                return true;
            }
            this.Page.Validate(this._modelValidationGroup);
            return this.Page.IsValid;
        }



        private void CreateWhereFields(Control c)
        {
            if (c is IQueryCondition)
            {
                IQueryCondition ic = c as IQueryCondition;
                if (null != ic.QueryProperty && !string.IsNullOrEmpty(ic.QueryProperty))
                    if (!string.IsNullOrEmpty(ic.QueryOperator.ToString()))
                        WhereFields.Add(ic.QueryField, ic.QueryOperator, ic.QueryProperty, true);
                    else if (null != ic.QueryExpression)
                        WhereFields.Add(ic.QueryExpression);
                    else
                        WhereFields.Add(ic.QueryField, OperatorType.Equals, ic.QueryProperty, true);
            }
        }
        #endregion

        #region IPostBackEventHandler 成员

        public void RaisePostBackEvent(string eventArgument)
        {
            int index = eventArgument.IndexOf('$');
            if (index >= 0)
            {
                CommandEventArgs originalArgs = new CommandEventArgs(eventArgument.Substring(0, index), eventArgument.Substring(index + 1));
                ContainerCommandEventArgs e = new ContainerCommandEventArgs(this, originalArgs);
                this.HandleEvent(this, e, false, string.Empty);
            }
        }

        #endregion


        #region handle help

        private void HandleEdit()
        {
            ContainerViewModeEventArgs e = new ContainerViewModeEventArgs(ContainerMode.Edit, false);
            this.OnModeChanging(e);
            if (!e.Cancel)
            {
                if (base.IsBoundUsingDataSourceID)
                {
                    this.ViewMode = e.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                }
                base.RequiresDataBinding = true;
            }
        }

        private void HandleUpdate(string commandArg, bool causesValidation)
        {
            if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
            {
                if (this.ViewMode != ContainerMode.Edit)
                {
                    throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContainerMustBeInEditMode"), this.ID));
                }
                DataSourceView data = null;
                bool _isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
                if (_isBoundUsingDataSourceID)
                {
                    data = this.GetData();
                    if (data == null)
                    {
                        throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionDataSourceViewReturnedNullView"), this.ID));
                    }
                }
                ContainerUpdateEventArgs e = new ContainerUpdateEventArgs(commandArg);
                if (_isBoundUsingDataSourceID)
                {
                    foreach (DictionaryEntry entry in this.BoundFieldValues)
                    {
                        e.OldValues.Add(entry.Key, entry.Value);
                    }
                    this.ExtractRowValues(e.NewValues, true);
                    foreach (DictionaryEntry entry2 in this.DataKey.Values)
                    {
                        e.Keys.Add(entry2.Key, entry2.Value);
                    }
                }
                this.OnItemUpdating(e);
                if (!e.Cancel && _isBoundUsingDataSourceID)
                {
                    this._updateKeys = e.Keys;
                    this._updateOldValues = e.OldValues;
                    this._updateNewValues = e.NewValues;

                    //redo update process begin
                    foreach (DictionaryEntry de in _updateKeys)
                    {
                        if (_updateKeys.Contains(de.Key))
                          this.updateWhereFields.Add(de.Key, de.Value);
                    }
                    e.Keys.Clear();
                    e.Keys.Add("fields", this.updateWhereFields);

                    foreach (DictionaryEntry de1 in _updateNewValues)
                    {
                        if (_updateOldValues.Contains(de1.Key)&&_updateOldValues[de1.Key].ToString() != de1.Value.ToString())
                           this.updateFields.Add(de1.Key, de1.Value);
                    }
                    e.NewValues.Clear();
                    e.NewValues.Add("updateFields", this.updateFields);
                    //redo update process end

                    data.Update(e.Keys, e.NewValues, e.OldValues, new DataSourceViewOperationCallback(this.HandleUpdateCallback));
                }
            }
        }

        private bool HandleUpdateCallback(int affectedRows, Exception ex)
        {
            ContainerUpdatedEventArgs e = new ContainerUpdatedEventArgs(affectedRows, ex);
            e.SetOldValues(this._updateOldValues);
            e.SetNewValues(this._updateNewValues);
            e.SetKeys(this._updateKeys);
            this.OnItemUpdated(e);
            this._updateKeys = null;
            this._updateOldValues = null;
            this._updateNewValues = null;
            if ((ex != null) && !e.ExceptionHandled)
            {
                if (this.PageIsValidAfterModelException())
                {
                    return false;
                }
                e.KeepInEditMode = true;
            }
            if (!e.KeepInEditMode)
            {
                ContainerViewModeEventArgs args2 = new ContainerViewModeEventArgs(this.DefaultMode, false);
                this.OnModeChanging(args2);
                if (!args2.Cancel)
                {
                    this.ViewMode = args2.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                    base.RequiresDataBinding = true;
                }
            }
            return true;
        }

        private void HandleInsert(string commandArg, bool causesValidation)
        {
            if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
            {
                if (this.ViewMode != ContainerMode.Insert)
                {
                    throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionContainerMustBeInInsertMode"), this.ID));
                }
                DataSourceView data = null;
                bool _isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
                if (_isBoundUsingDataSourceID)
                {
                    data = this.GetData();
                    if (data == null)
                    {
                        throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionDataSourceViewReturnedNullView"), this.ID));
                    }
                }
                ContainerInsertEventArgs e = new ContainerInsertEventArgs(commandArg);
                if (_isBoundUsingDataSourceID)
                {
                    this.ExtractRowValues(e.Values, true);
                }
                this.OnItemInserting(e);
                if (!e.Cancel && _isBoundUsingDataSourceID)
                {
                    this._insertValues = e.Values;

                    // redo insert process begin
                    foreach (DictionaryEntry de in _insertValues)
                    {
                        this.insertFields.Add(de.Key, de.Value);
                    }
                    e.Values.Clear();
                    e.Values.Add("fields",this.insertFields);
                    // redo insert process end

                    data.Insert(e.Values, new DataSourceViewOperationCallback(this.HandleInsertCallback));
                }
            }
        }

        private bool HandleInsertCallback(int affectedRows, Exception ex)
        {
            ContainerInsertedEventArgs e = new ContainerInsertedEventArgs(affectedRows, ex);
            e.SetValues(this._insertValues);
            this.OnItemInserted(e);
            this._insertValues = null;
            if ((ex != null) && !e.ExceptionHandled)
            {
                if (this.PageIsValidAfterModelException())
                {
                    return false;
                }
                e.KeepInInsertMode = true;
            }
            if (!e.KeepInInsertMode)
            {
                ContainerViewModeEventArgs args2 = new ContainerViewModeEventArgs(this.DefaultMode, false);
                this.OnModeChanging(args2);
                if (!args2.Cancel)
                {
                    this.ViewMode = args2.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                    base.RequiresDataBinding = true;
                }
            }
            return true;
        }

        private void HandleNew()
        {
            ContainerViewModeEventArgs e = new ContainerViewModeEventArgs(ContainerMode.Insert, false);
            this.OnModeChanging(e);
            if (!e.Cancel)
            {
                if (base.IsBoundUsingDataSourceID)
                {
                    this.ViewMode = e.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                }
                base.RequiresDataBinding = true;
            }
        }

        private void HandleCancel()
        {
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            ContainerViewModeEventArgs e = new ContainerViewModeEventArgs(this.DefaultMode, true);
            this.OnModeChanging(e);
            if (!e.Cancel)
            {
               // if (isBoundUsingDataSourceID)
                //{
                    this.ViewMode = e.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                //}
                base.RequiresDataBinding = true;
            }
        }

        private void HandleDelete(string commandArg)
        {
            //if (this.PageIndex >= 0)
            //{
            DataSourceView data = null;
            bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
            if (isBoundUsingDataSourceID)
            {
                data = this.GetData();
                if (data == null)
                {
                    throw new HttpException(string.Format(AssemblyResourceManager.ExceptionResource.GetString("ExceptionDataSourceViewReturnedNullView"), this.ID));
                }
            }
            ContainerDeleteEventArgs e = new ContainerDeleteEventArgs(/*pageIndex*/);
            if (isBoundUsingDataSourceID)
            {
                this.ExtractRowValues(e.Values, true);
                foreach (DictionaryEntry entry in this.DataKey.Values)
                {
                    e.Keys.Add(entry.Key, entry.Value);
                    if (e.Values.Contains(entry.Key))
                    {
                        e.Values.Remove(entry.Key);
                    }
                }
            }
            this.OnItemDeleting(e);
            if (!e.Cancel && isBoundUsingDataSourceID)
            {
                this._deleteKeys = e.Keys;
                this._deleteValues = e.Values;

                //redo delete process begin
                foreach (DictionaryEntry de in _deleteKeys)
                {
                    this.deleteFields.Add(de.Key, de.Value);
                }
                e.Keys.Clear();
                e.Keys.Add("fields", this.deleteFields);
                //redo delete process end

                data.Delete(e.Keys, e.Values, new DataSourceViewOperationCallback(this.HandleDeleteCallback));
            }
            // }
        }

        private void HandleQuery()
        {
            ContainerViewModeEventArgs e = new ContainerViewModeEventArgs(ContainerMode.Query, false);
            this.OnModeChanging(e);
            if (!e.Cancel)
            {
                //if (base.IsBoundUsingDataSourceID)
                //{
                    this.ViewMode = e.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                //}
                base.RequiresDataBinding = true;
            }


            //this.ExtractValues();
            ContainQueryEventArgs qe = new ContainQueryEventArgs(this.WhereFields);
            if (!qe.Cancel)
            {
                this.OnQuerying(qe);
            }

        }

        private void HandleItem()
        {
            ContainerViewModeEventArgs e = new ContainerViewModeEventArgs(ContainerMode.Item, false);
            this.OnModeChanging(e);
            if (!e.Cancel)
            {
                //if (base.IsBoundUsingDataSourceID)
                //{
                    this.ViewMode = e.NewMode;
                    this.OnModeChanged(EventArgs.Empty);
                //}
                base.RequiresDataBinding = true;
            }
        }

        private bool HandleDeleteCallback(int affectedRows, Exception ex)
        {
            //int pageIndex = this.PageIndex;
            ContainerDeletedEventArgs e = new ContainerDeletedEventArgs(affectedRows, ex);
            e.SetKeys(this._deleteKeys);
            e.SetValues(this._deleteValues);
            this.OnItemDeleted(e);
            this._deleteKeys = null;
            this._deleteValues = null;
            if (((ex != null) && !e.ExceptionHandled) && this.PageIsValidAfterModelException())
            {
                return false;
            }
            //if (pageIndex == (this._pageCount - 1))
            //{
            //    this.HandlePage(pageIndex - 1);
            //}
            base.RequiresDataBinding = true;
            return true;
        }

        private void HandleSelect()
        {
            this.isSelecting = true;
        }

        private bool HandleEvent(object source, EventArgs e, bool causesValidation, string validationGroup)
        {
            bool flag = false;
            this._modelValidationGroup = null;
            if (causesValidation && (this.Page != null))
            {
                this.Page.Validate(validationGroup);
                if (this.EnableModelValidation)
                {
                    this._modelValidationGroup = validationGroup;
                }
            }
            //ContainerCommandEventArgs args = e as ContainerCommandEventArgs;
            ContainerCommandEventArgs args = new ContainerCommandEventArgs(source, (CommandEventArgs)e);
            if (args == null)
            {
                return flag;
            }
            this.OnItemCommand(args);
            flag = true;
            string commandName = args.CommandName.ToUpper();
            if (0 == string.Compare(commandName, "EDIT", true))
            {
                HandleEdit();
                return flag;
            }
            else if (0 == string.Compare(commandName, "CANCEL", true))
            {
                HandleCancel();
                flag = false;
                return flag;
            }
            else if (0 == string.Compare(commandName, "UPDATE", true))
            {
                HandleUpdate((string)args.CommandArgument, causesValidation);
                return flag;
            }
            else if (0 == string.Compare(commandName, "INSERT", true))
            {
                HandleInsert((string)args.CommandArgument, causesValidation);
                return flag;
            }
            else if (0 == string.Compare(commandName, "NEW", true))
            {
                HandleNew();
                return flag;
            }
            else if (0 == string.Compare(commandName, "DELETE", true))
            {
                this.HandleDelete((string)args.CommandArgument);
                return flag;
            }
            else if (0 == string.Compare(commandName, "QUERY", true))
            {
                this.HandleQuery();
                return flag;
            }
            else if (0 == string.Compare(commandName, "ITEM", true))
            {
                this.HandleItem(); 
                return flag;
            }
            else if (0 == string.Compare(commandName, "SELECT", true))
            {
                this.HandleSelect();
                return flag;
            }
            return false;
        }


        #endregion

        #region viewstate
        protected override object SaveViewState()
        {
            object _baseViewState = base.SaveViewState();
            object _boundFieldValueViewState = (this._boundFieldValues != null) ? Water.Web.Controls.Util.OrderedDictionaryStateHelper.SaveViewState(this._boundFieldValues) : null;
            return new object[] { _baseViewState, _boundFieldValueViewState };
        }
        protected override void LoadViewState(object savedState)
        {
            if (savedState != null)
            {
                object[] objArray = (object[])savedState;
                base.LoadViewState(objArray[0]);
                if (objArray[1] != null)
                    Water.Web.Controls.Util.OrderedDictionaryStateHelper.LoadViewState(this.BoundFieldValues, (ArrayList)objArray[1]);
            }
            else
                base.LoadViewState(null);
        }
        protected override void TrackViewState()
        {
            base.TrackViewState();
        }
        //protected override object SaveControlState()
        //{
        //    object _baseControlState= base.SaveControlState();
        //}
        #endregion

        #region IDataItemContainer 成员

        public virtual object DataItem
        {
            get
            {
                if (this.dataItem != null)
                    return this.dataItem;
                else
                {
                    for (Control c = this.Parent; c != this.Page; c = c.Parent)
                    {
                        if (c is IDataItemContainer)
                        {
                            IDataItemContainer _dataItem = c as IDataItemContainer;
                            if (_dataItem.DataItem != null)
                                return _dataItem.DataItem;
                        }
                    }
                    return this.dataItem;
                }
            }
            set
            {
                this.dataItem = value;
            }
        }

        public int DataItemIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        public int DisplayIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        #endregion
    }


    [TypeConverter(typeof(ExpandableObjectConverter))]
    public sealed class HeaderFooterInfo
    {

        private HorizontalAlign align;

        [NotifyParentProperty(true), Category("Appearance"), Browsable(true)]
        public HorizontalAlign Align
        {
            get { return align; }
            set { align = value; }
        }

        private string cssClass;

        [NotifyParentProperty(true), DefaultValue(""), Category("Appearance"), CssClassProperty, Browsable(true)]
        public string CssClass
        {
            get { return cssClass; }
            set { cssClass = value; }
        }


        public override string ToString()
        {
            return this.Align.ToString() + " " +
                   this.CssClass;
        }
    }


    [ToolboxItem(false)]
    public class HeaderFooterContainer : WebControl, INamingContainer, IDataItemContainer
    {
        private object dataItem;
        private int itemIndex;

        public HeaderFooterContainer()
        { 
        }
        public HeaderFooterContainer(object dataItem)
        {
            this.dataItem = dataItem;
        }

        protected override bool OnBubbleEvent(object source, EventArgs e)
        {
            if (e is CommandEventArgs)
            {
                ContainerCommandEventArgs args = new ContainerCommandEventArgs(source, (CommandEventArgs)e);
                base.RaiseBubbleEvent(this, args);
                return true;
            }
            return false;

        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

        #region IDataItemContainer 成员

        public virtual object DataItem
        {
            get
            {
                if (this.dataItem != null)
                    return this.dataItem;
                else
                {
                    for (Control c = this.Parent; c != this.Page; c = c.Parent)
                    {
                        if (c is IDataItemContainer)
                        {
                            IDataItemContainer _dataItem = c as IDataItemContainer;
                            if (_dataItem.DataItem != null)
                                return _dataItem.DataItem;
                        }
                    }
                    return this.dataItem;
                }
            }
            set
            {
                this.dataItem = value;
            }
        }

        public int DataItemIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        public int DisplayIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        #endregion
    }


    [ToolboxItem(false)]
    public class ContainerItem : WebControl, INamingContainer, IDataItemContainer
    {
        private object dataItem;
        private int itemIndex;
        private WhereFields whereFields = new WhereFields();
        private bool isCreateWhereFields = false;

        public ContainerItem() { }
        public ContainerItem(object dataItem)
        {
            this.dataItem = dataItem;
        }

        protected override bool OnBubbleEvent(object source, EventArgs e)
        {
            if (e is CommandEventArgs)
            {
                ContainerCommandEventArgs args = new ContainerCommandEventArgs(source, (CommandEventArgs)e);
                base.RaiseBubbleEvent(this, args);
                return true;
            }
            return false;

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            //EnsureCreateWhereFields();
        }

        private void EnsureCreateWhereFields()
        {
            if (!this.isCreateWhereFields)
            {
                EnsureCreateWhereFieldsHelp(this.Controls);
                /*
                foreach (Control obj in this.Controls)
                {
                    string _queryOperator = null;
                    string _queryField = null;
                    string _queryValue = null;
                    string _queryExpression = null;
                    string _queryValueFromPropertyName = null;

                    if (obj is IQueryCondition)
                    {
                        IQueryCondition ic = obj as IQueryCondition;
                        _queryOperator = ic.QueryOperator.ToString();
                        _queryField = ic.QueryField;
                        _queryValueFromPropertyName = ic.QueryProperty;
                        if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                            _queryValue = DataBinder.Eval(obj, _queryValueFromPropertyName).ToString();
                        _queryExpression = ic.QueryExpression;
                    }
                    else if (obj is WebControl)
                    {
                        WebControl c = (WebControl)obj;
                        _queryOperator = c.Attributes["QueryOperator"];
                        _queryField = c.Attributes["QueryField"];
                        _queryValueFromPropertyName = c.Attributes["QueryProperty"];
                        if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                            _queryValue = DataBinder.Eval(c, _queryValueFromPropertyName).ToString();
                        _queryExpression = c.Attributes["QueryExpression"];
                    }
                    else if (obj is System.Web.UI.HtmlControls.HtmlControl)
                    {
                        System.Web.UI.HtmlControls.HtmlControl c = (System.Web.UI.HtmlControls.HtmlControl)obj;
                        _queryOperator = c.Attributes["QueryOperator"];
                        _queryField = c.Attributes["QueryField"];
                        _queryValueFromPropertyName = c.Attributes["QueryProperty"];
                        if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                            _queryValue = DataBinder.Eval(c, _queryValueFromPropertyName).ToString();
                        _queryExpression = c.Attributes["QueryExpression"];
                    }
                    this.isCreateWhereFields = true;
                    //set where fields
                    if (!string.IsNullOrEmpty(_queryField))
                    {
                        if (string.IsNullOrEmpty(_queryValueFromPropertyName))  //if the QueryField property is seted,follow the QueryProperty property must be seted
                            throw new Exception(string.Format(ExceptionResource.ExceptionQueryPropertyNotFound, obj.ID));//if no set the  QueryProperty property ,when page load can find error

                        if (!string.IsNullOrEmpty(_queryValue))
                        {
                            if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                            {
                                if (!string.IsNullOrEmpty(_queryOperator))
                                {
                                    int _intQueryOperator = (int)(Enum.Parse(typeof(OperatorType), _queryOperator));
                                    WhereFields.Add(_queryField, (OperatorType)_intQueryOperator, _queryValue);
                                }
                                else if (!string.IsNullOrEmpty(_queryExpression))
                                    WhereFields.Add(_queryExpression);
                                else
                                    WhereFields.Add(_queryField, OperatorType.Equals, _queryValue);
                            }
                        }
                    }
                }
                 */
            }
            
        }
        private void EnsureCreateWhereFieldsHelp(ControlCollection childs)
        {
            foreach (Control obj in childs)
            {
                string _queryOperator = null;
                string _queryField = null;
                string _queryValue = null;
                string _queryExpression = null;
                string _queryValueFromPropertyName = null;

                if (obj is IQueryCondition)
                {
                    IQueryCondition ic = obj as IQueryCondition;
                    _queryOperator = ic.QueryOperator.ToString();
                    _queryField = ic.QueryField;
                    _queryValueFromPropertyName = ic.QueryProperty;
                    if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                        _queryValue = DataBinder.Eval(obj, _queryValueFromPropertyName).ToString();
                    _queryExpression = ic.QueryExpression;
                }
                else if (obj is WebControl)
                {
                    WebControl c = (WebControl)obj;
                    _queryOperator = c.Attributes["QueryOperator"];
                    _queryField = c.Attributes["QueryField"];
                    _queryValueFromPropertyName = c.Attributes["QueryProperty"];
                    if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                        _queryValue = DataBinder.Eval(c, _queryValueFromPropertyName).ToString();
                    _queryExpression = c.Attributes["QueryExpression"];
                }
                else if (obj is System.Web.UI.HtmlControls.HtmlControl)
                {
                    System.Web.UI.HtmlControls.HtmlControl c = (System.Web.UI.HtmlControls.HtmlControl)obj;
                    _queryOperator = c.Attributes["QueryOperator"];
                    _queryField = c.Attributes["QueryField"];
                    _queryValueFromPropertyName = c.Attributes["QueryProperty"];
                    if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                        _queryValue = DataBinder.Eval(c, _queryValueFromPropertyName).ToString();
                    _queryExpression = c.Attributes["QueryExpression"];
                }
                this.isCreateWhereFields = true;
                //set where fields
                if (!string.IsNullOrEmpty(_queryField))
                {
                    if (string.IsNullOrEmpty(_queryValueFromPropertyName))  //if the QueryField property is seted,follow the QueryProperty property must be seted
                        throw new Exception(string.Format(ExceptionResource.ExceptionQueryPropertyNotFound, obj.ID));//if no set the  QueryProperty property ,when page load can find error

                    if (!string.IsNullOrEmpty(_queryValue)/* && !string.IsNullOrEmpty(_queryField)*/)
                    {
                        if (!string.IsNullOrEmpty(_queryValueFromPropertyName))
                        {
                            if (!string.IsNullOrEmpty(_queryOperator))
                            {
                                int _intQueryOperator = (int)(Enum.Parse(typeof(OperatorType), _queryOperator));
                                WhereFields.Add(_queryField, (OperatorType)_intQueryOperator, _queryValue);
                            }
                            else if (!string.IsNullOrEmpty(_queryExpression))
                                WhereFields.Add(_queryExpression);
                            else
                                WhereFields.Add(_queryField, OperatorType.Equals, _queryValue);
                        }
                    }
                }
                //递归
                if (obj.HasControls())
                    EnsureCreateWhereFieldsHelp(obj.Controls);
            }
        }

        public virtual object DataItem
        {
            get
            {
                if (this.dataItem != null)
                    return this.dataItem;
                else
                {
                    for (Control c = this.Parent; c != this.Page; c = c.Parent)
                    {
                        if (c is IDataItemContainer)
                        { 
                            IDataItemContainer _dataItem=c as  IDataItemContainer;
                            if (_dataItem.DataItem != null)
                                return _dataItem.DataItem;
                        }
                    }
                    return this.dataItem;
                }
            }
            set
            {
                this.dataItem = value;
            }
        }

        internal WhereFields WhereFields
        {
            get 
            {
                EnsureCreateWhereFields(); 
                return whereFields;
            }
            set { whereFields = value; }
        }

        #region IDataItemContainer 成员


        public int DataItemIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        public int DisplayIndex
        {
            get
            {
                if (this.dataItem != null)
                    this.itemIndex = 1;
                return itemIndex;
            }
        }

        #endregion
    }


    #region eventargs
    public class ContainerCommandEventArgs : CommandEventArgs
    {
        // Fields
        private object _commandSource;

        // Methods
        public ContainerCommandEventArgs(object commandSource, CommandEventArgs originalArgs)
            : base(originalArgs)
        {
            this._commandSource = commandSource;
        }

        // Properties
        public object CommandSource
        {
            get
            {
                return this._commandSource;
            }
        }
    }

    public class ContainerViewModeEventArgs : CancelEventArgs
    {
        // Fields
        private bool _cancelingEdit;
        private ContainerMode _mode;

        // Methods
        public ContainerViewModeEventArgs(ContainerMode mode, bool cancelingEdit)
            : base(false)
        {
            this._mode = mode;
            this._cancelingEdit = cancelingEdit;
        }

        // Properties
        public bool CancelingEdit
        {
            get
            {
                return this._cancelingEdit;
            }
        }

        public ContainerMode NewMode
        {
            get
            {
                return this._mode;
            }
            set
            {
                this._mode = value;
            }
        }
    }

    public class ContainerDeletedEventArgs : EventArgs
    {
        // Fields
        private int _affectedRows;
        private Exception _exception;
        private bool _exceptionHandled;
        private IOrderedDictionary _keys;
        private IOrderedDictionary _values;

        // Methods
        public ContainerDeletedEventArgs(int affectedRows, Exception e)
        {
            this._affectedRows = affectedRows;
            this._exceptionHandled = false;
            this._exception = e;
        }

        internal void SetKeys(IOrderedDictionary keys)
        {
            this._keys = keys;
        }

        internal void SetValues(IOrderedDictionary values)
        {
            this._values = values;
        }

        // Properties
        public int AffectedRows
        {
            get
            {
                return this._affectedRows;
            }
        }

        public Exception Exception
        {
            get
            {
                return this._exception;
            }
        }

        public bool ExceptionHandled
        {
            get
            {
                return this._exceptionHandled;
            }
            set
            {
                this._exceptionHandled = value;
            }
        }

        public IOrderedDictionary Keys
        {
            get
            {
                if (this._keys == null)
                {
                    this._keys = new OrderedDictionary();
                }
                return this._keys;
            }
        }

        public IOrderedDictionary Values
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }

    }

    public class ContainerDeleteEventArgs : CancelEventArgs
    {
        // Fields
        private OrderedDictionary _keys;
        // private int _rowIndex;
        private OrderedDictionary _values;

        // Methods
        public ContainerDeleteEventArgs(/*int rowIndex*/)
            : base(false)
        {
            //this._rowIndex = rowIndex;
        }

        // Properties
        public IOrderedDictionary Keys
        {
            get
            {
                if (this._keys == null)
                {
                    this._keys = new OrderedDictionary();
                }
                return this._keys;
            }
        }

        //public int RowIndex
        //{
        //    get
        //    {
        //        return this._rowIndex;
        //    }
        //}

        public IOrderedDictionary Values
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }
    }

    public class ContainerInsertedEventArgs : EventArgs
    {
        // Fields
        private int _affectedRows;
        private Exception _exception;
        private bool _exceptionHandled;
        private bool _keepInInsertMode;
        private IOrderedDictionary _values;

        // Methods
        public ContainerInsertedEventArgs(int affectedRows, Exception e)
        {
            this._affectedRows = affectedRows;
            this._exceptionHandled = false;
            this._exception = e;
            this._keepInInsertMode = false;
        }

        internal void SetValues(IOrderedDictionary values)
        {
            this._values = values;
        }

        // Properties
        public int AffectedRows
        {
            get
            {
                return this._affectedRows;
            }
        }

        public Exception Exception
        {
            get
            {
                return this._exception;
            }
        }

        public bool ExceptionHandled
        {
            get
            {
                return this._exceptionHandled;
            }
            set
            {
                this._exceptionHandled = value;
            }
        }

        public bool KeepInInsertMode
        {
            get
            {
                return this._keepInInsertMode;
            }
            set
            {
                this._keepInInsertMode = value;
            }
        }

        public IOrderedDictionary Values
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }
    }

    public class ContainerInsertEventArgs : CancelEventArgs
    {
        // Fields
        private object _commandArgument;
        private OrderedDictionary _values;

        // Methods
        public ContainerInsertEventArgs(object commandArgument)
            : base(false)
        {
            this._commandArgument = commandArgument;
        }

        // Properties
        public object CommandArgument
        {
            get
            {
                return this._commandArgument;
            }
        }

        public IOrderedDictionary Values
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }
    }

    public class ContainerUpdatedEventArgs : EventArgs
    {
        // Fields
        private int _affectedRows;
        private Exception _exception;
        private bool _exceptionHandled;
        private bool _keepInEditMode;
        private IOrderedDictionary _keys;
        private IOrderedDictionary _oldValues;
        private IOrderedDictionary _values;

        // Methods
        public ContainerUpdatedEventArgs(int affectedRows, Exception e)
        {
            this._affectedRows = affectedRows;
            this._exceptionHandled = false;
            this._exception = e;
            this._keepInEditMode = false;
        }

        internal void SetKeys(IOrderedDictionary keys)
        {
            this._keys = keys;
        }

        internal void SetNewValues(IOrderedDictionary newValues)
        {
            this._values = newValues;
        }

        internal void SetOldValues(IOrderedDictionary oldValues)
        {
            this._oldValues = oldValues;
        }

        // Properties
        public int AffectedRows
        {
            get
            {
                return this._affectedRows;
            }
        }

        public Exception Exception
        {
            get
            {
                return this._exception;
            }
        }

        public bool ExceptionHandled
        {
            get
            {
                return this._exceptionHandled;
            }
            set
            {
                this._exceptionHandled = value;
            }
        }

        public bool KeepInEditMode
        {
            get
            {
                return this._keepInEditMode;
            }
            set
            {
                this._keepInEditMode = value;
            }
        }

        public IOrderedDictionary Keys
        {
            get
            {
                if (this._keys == null)
                {
                    this._keys = new OrderedDictionary();
                }
                return this._keys;
            }
        }

        public IOrderedDictionary NewValues
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }

        public IOrderedDictionary OldValues
        {
            get
            {
                if (this._oldValues == null)
                {
                    this._oldValues = new OrderedDictionary();
                }
                return this._oldValues;
            }
        }
    }

    public class ContainerUpdateEventArgs : CancelEventArgs
    {
        // Fields
        private object _commandArgument;
        private OrderedDictionary _keys;
        private OrderedDictionary _oldValues;
        private OrderedDictionary _values;

        // Methods
        public ContainerUpdateEventArgs(object commandArgument)
            : base(false)
        {
            this._commandArgument = commandArgument;
        }

        // Properties
        public object CommandArgument
        {
            get
            {
                return this._commandArgument;
            }
        }

        public IOrderedDictionary Keys
        {
            get
            {
                if (this._keys == null)
                {
                    this._keys = new OrderedDictionary();
                }
                return this._keys;
            }
        }

        public IOrderedDictionary NewValues
        {
            get
            {
                if (this._values == null)
                {
                    this._values = new OrderedDictionary();
                }
                return this._values;
            }
        }

        public IOrderedDictionary OldValues
        {
            get
            {
                if (this._oldValues == null)
                {
                    this._oldValues = new OrderedDictionary();
                }
                return this._oldValues;
            }
        }
    }

    public class ContainQueryEventArgs : CancelEventArgs
    {
        //fields
        private WhereFields _whereFields;

        // Methods
        public ContainQueryEventArgs(WhereFields whereFields)
        {
            this._whereFields = whereFields;
        }

        // Properties
        public WhereFields WhereFields
        {
            get { return _whereFields; }
            set { _whereFields = value; }
        }
    }

    #endregion


    #region delegate
    public delegate void ContainerCommandEventHandler(object sender, ContainerCommandEventArgs e);

    public delegate void ContaineViewModeEventHandler(object sender, ContainerViewModeEventArgs e);

    public delegate void ContainerDeletedEventHandler(object sender, ContainerDeletedEventArgs e);

    public delegate void ContainerDeleteEventHandler(object sender, ContainerDeleteEventArgs e);

    public delegate void ContainerInsertedEventHandler(object sender, ContainerInsertedEventArgs e);

    public delegate void ContainerInsertEventHandler(object sender, ContainerInsertEventArgs e);

    public delegate void ContainerUpdatedEventHandler(object sender, ContainerUpdatedEventArgs e);

    public delegate void ContainerUpdateEventHandler(object sender, ContainerUpdateEventArgs e);

    public delegate void ContainerQueryEventHandler(object sender, ContainQueryEventArgs e);

    #endregion

}
